package com.bjb.vr.common.utils;

import com.alibaba.fastjson.JSONObject;
import com.bjb.vr.common.config.HttpClientConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Map;

/**
 * HttpClient 请求工具类
 */
@Slf4j
public class HttpClientProxy {

    /**
     * 发送HTTP的GET请求
     *
     * @param requestUrl
     * @param params
     * @return
     * @throws IOException
     */
    public static byte[] get(String requestUrl, String params) throws IOException {
        HttpGet HttpGet = new HttpGet(requestUrl + params);
        try {
            CloseableHttpResponse httpResponse = HttpClientConfig.getHttpClient().execute(HttpGet);
            return processResponseToBytes(httpResponse);
        } finally {
            HttpGet.releaseConnection();
        }
    }

    /**
     * 发送HTTP的GET请求
     *
     * @param requestUrl
     * @return
     * @throws IOException
     */
    public static byte[] get(String requestUrl) throws IOException {
        HttpGet HttpGet = new HttpGet(requestUrl);
        try {
            CloseableHttpResponse httpResponse = HttpClientConfig.getHttpClient().execute(HttpGet);
            return processResponseToBytes(httpResponse);
        } finally {
            HttpGet.releaseConnection();
        }
    }


    /**
     * 发送HTTP的POST请求
     *
     * @param requestUrl
     * @param requestData
     * @param headers
     * @return
     * @throws IOException
     */
    public static String post(String requestUrl, JSONObject requestData, Map<String, String> headers) throws Exception {
        HttpPost httpPost = new HttpPost(requestUrl);
        if (headers != null && headers.size() > 0) {
            for (String name : headers.keySet()) {
                String value = headers.get(name);
                httpPost.setHeader(name, value);
            }
        }
        StringEntity stringEntity = new StringEntity(requestData.toString(), Charset.forName("UTF-8"));
        stringEntity.setContentEncoding("UTF-8");
        stringEntity.setContentType("application/json");
        httpPost.setEntity(stringEntity);

        try {
            log.info("发起请求的地址:{}", httpPost.getRequestLine());
            log.info("发起请求的格式和编码:{} | {}", stringEntity.getContentType(), stringEntity.getContentEncoding());
            CloseableHttpResponse httpResponse = HttpClientConfig.getHttpClient().execute(httpPost);
            log.info("----------------------------------------");
            // 打印响应状态
            log.info(httpResponse.getStatusLine().toString());
            return processResponseToString(httpResponse);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            httpPost.releaseConnection();
        }
    }

    /**
     * 发送HTTP的POST请求
     *
     * @param requestUrl
     * @param jsonObject
     * @return
     * @throws IOException
     */
    public static String post(String requestUrl, JSONObject jsonObject) throws Exception {
        HttpPost httpPost = new HttpPost(requestUrl);
        StringEntity stringEntity = new StringEntity(jsonObject.toString());
        stringEntity.setContentEncoding("UTF-8");
        stringEntity.setContentType("application/json");
        httpPost.setEntity(stringEntity);
        try {
            log.info("发起请求的地址:" + httpPost.getRequestLine());
            log.info("发起请求的格式:" + stringEntity.getContentType().toString());
            CloseableHttpResponse httpResponse = HttpClientConfig.getHttpClient().execute(httpPost);
            log.info("----------------------------------------");
            // 打印响应状态
            log.info(httpResponse.getStatusLine().toString());
            return processResponseToString(httpResponse);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            httpPost.releaseConnection();
        }
    }

    /**
     * 处理响应信息
     *
     * @param httpResponse
     * @return
     * @throws IOException
     */
    private static byte[] processResponseToBytes(CloseableHttpResponse httpResponse) throws IOException {
        byte[] byt = null;
        try {
            HttpEntity resEntity = httpResponse.getEntity();
            if (resEntity != null) {
                InputStream stream = resEntity.getContent();
                byt = IOUtils.toByteArray(stream);
            }
            EntityUtils.consume(resEntity);
            return byt;
        } finally {
            if (null != httpResponse) {
                httpResponse.close();
            }
        }
    }

    /**
     * 处理响应信息
     *
     * @param httpResponse
     * @return
     * @throws IOException
     */
    private static String processResponseToString(CloseableHttpResponse httpResponse) throws IOException {
        String result = null;
        try {
            HttpEntity resEntity = httpResponse.getEntity();
            if (resEntity != null) {
                result = EntityUtils.toString(resEntity, "UTF-8");
                // 打印响应内容
                if (StringUtils.isNotBlank(result)) {
                    if (isJson(result)) {
                        JSONObject json = JSONObject.parseObject(result);
                        result = json.toString();
                    }
                    log.info("Response=" + result);
                } else {
                    log.info("Response=" + result);
                }
            }
            EntityUtils.consume(resEntity);
            return result;
        } finally {
            if (null != httpResponse) {
                httpResponse.close();
            }
        }
    }

    /**
     * 判断是否为字符串
     *
     * @param content
     * @return
     */
    public static boolean isJson(String content) {
        try {
            JSONObject jsonStr = JSONObject.parseObject(content);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}
